package com.zlyx.easy.core.map;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.zlyx.easy.core.collections.EasyList;
import com.zlyx.easy.core.collections.Lists;
import com.zlyx.easy.core.utils.JsonUtils;
import com.zlyx.easy.core.utils.ObjectUtils;

/**
 * @author 赵光
 * @desc Map封装
 * @Date 2018年11月26日 下午4:24:19
 */
public class EasyMap<K, V> extends HashMap<K, V> {

	private static final long serialVersionUID = 1L;

	public EasyMap() {
	}

	/**
	 * addValue
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public EasyMap<K, V> addValue(K key, V value) {
		put(key, value);
		return this;
	}

	/**
	 * addValue
	 * 
	 * @param map
	 * @return
	 */
	public EasyMap<K, V> addValue(Map<K, V> map) {
		putAll(map);
		return this;
	}

	/**
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean putNoNull(K key, V value) {
		if (ObjectUtils.anyEmpty(key, value)) {
			return false;
		}
		this.put(key, value);
		return true;
	}

	/**
	 * getInt
	 * 
	 * @param key
	 * @return
	 */
	public Integer getInt(String key) {
		return Integer.parseInt(getString(key));
	}

	/**
	 * getLong
	 * 
	 * @param key
	 * @return
	 */
	public Long getLong(String key) {
		return Long.parseLong(getString(key));
	}

	/**
	 * getString
	 * 
	 * @param key
	 * @return
	 */
	public String getString(String key) {
		return String.valueOf(get(key));
	}

	/**
	 * getMap
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public <M, N> EasyMap<M, N> getMap(String key) throws Exception {
		Object value = get(key);
		if (value == null) {
			return null;
		}
		if (Map.class.isAssignableFrom(value.getClass())) {
			return Maps.newMap((Map<M, N>) value);
		}
		return JsonUtils.toMap(JsonUtils.toJson(value));
	}

	/**
	 * getList
	 * 
	 * @param <T>
	 * @param key
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public <T> EasyList<T> getList(String key) throws Exception {
		Object value = get(key);
		if (value == null) {
			return null;
		}
		if (List.class.isAssignableFrom(value.getClass())) {
			return Lists.newList((List<T>) value);
		}
		return JsonUtils.toList(JsonUtils.toJson(value));
	}

	/**
	 * getValue
	 * 
	 * @param <R>
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getValue(String key) {
		Object value = get(key);
		return value == null ? null : (T) value;
	}

	/**
	 * getValue
	 * 
	 * @param <R>
	 * @param key
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public <R> R getValue(String key, Class<R> cls) throws Exception {
		return JsonUtils.fromJson(get(key), cls);
	}

	/**
	 * withoutKey
	 * 
	 * @param key
	 * @return
	 */
	public boolean withoutKey(String key) {
		return !containsKey(key);
	}

	/**
	 * withoutKey
	 * 
	 * @param key
	 * @return
	 */
	public boolean withoutValue(V value) {
		return !containsValue(value);
	}

	/**
	 * notEmpty
	 * 
	 * @return
	 */
	public boolean isNotEmpty() {
		return !isEmpty();
	}

	/**
	 * 根据value取key
	 * 
	 * @param <K>
	 * @param <V>
	 * @param map
	 * @param value
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public K getKey(V value) {
		if (containsValue(value)) {
			Object[] values = values().toArray();
			for (int i = 0; i < values.length; i++) {
				if (values[i].equals(value)) {
					return (K) keySet().toArray()[i];
				}
			}
		}
		return null;
	}

	/**
	 * 反转map
	 * 
	 * @param map
	 * @return
	 */
	public EasyMap<V, K> revertMap() {
		EasyMap<V, K> revertMap = new EasyMap<>();
		for (Entry<K, V> entry : entrySet()) {
			revertMap.put(entry.getValue(), entry.getKey());
		}
		return revertMap;
	}

}
